package main

//
//import (
//	"bytes"
//	"errors"
//	"fmt"
//	"io"
//	"net"
//	"strconv"
//	"strings"
//	"sync"
//	"unsafe"
//)
//
//type WsProxy struct {
//	listener  *net.TCPListener
//	localAddr *net.TCPAddr
//	//targetAddr *net.TCPAddr
//
//	conMap map[string]*WsConn
//	mutex  sync.RWMutex
//	//locked bool
//}
//
//type WsConn struct {
//	id         string
//	doneCtx    context.Context
//	cancelFunc context.CancelFunc
//	sourceAddr string
//	localAddr  string
//	targetAddr string
//	sourceConn *websocket.Conn
//	targetConn *websocket.Conn
//	tcpProxy   *WsProxy
//}
//
//var (
//	errCanceled      = errors.New("operation was canceled")
//	errWSAECONNRESET = errors.New("wsarecv: An existing connection was forcibly closed by the remote host.")
//	errNetClosing    = errors.New("use of closed network connection")
//)
//
//var ProxyWs *WsProxy
//
//func Start() (err error) {
//	localTcpAddr, err := net.ResolveTCPAddr("tcp", fmt.Sprintf(":%d", 8888))
//	if err != nil {
//		return err
//	}
//	ProxyWs = &WsProxy{
//		localAddr: localTcpAddr,
//	}
//	ProxyWs.listener, err = net.ListenTCP("tcp", localTcpAddr)
//	if err != nil {
//		println(err)
//	}
//	ProxyWs.conMap = make(map[string]*WsConn)
//	go func() {
//		for {
//			conn, err := ProxyWs.AcceptTcp()
//			if err != nil {
//				if err.Error() == "reuse" {
//					continue
//				}
//				log.Error().Err(err).Msg("建立代理连接失败")
//				continue
//			}
//			fmt.Println("targetAddr", conn.targetAddr, "连接成功")
//			fmt.Println("targetAddr", conn.targetAddr, "连接成功")
//		}
//	}()
//	return nil
//}
//
//func (t *WsProxy) AcceptTcp() (conn *WsConn, err error) {
//	conn = &WsConn{
//		tcpProxy: t,
//	}
//	// 监听tcp连接，每创建一个连接就同步创建一个 WsConn 对象。同时开启3个协程，分别处理代理双方的数据交换 和 监听TcpConn 连接通道的关闭
//	conn.sourceConn, err = t.listener.AcceptTCP()
//	if err != nil {
//		return nil, err
//	}
//	conn.sourceAddr = conn.sourceConn.RemoteAddr().String()
//	conn.localAddr = conn.sourceConn.LocalAddr().String()
//	doneCtx, cancelFunc := context.WithCancel(context.Background())
//	conn.doneCtx = doneCtx
//	conn.cancelFunc = cancelFunc
//	//err = conn.readHeadBuildConnect()
//	if err != nil {
//		if err.Error() == "reuse" {
//			return nil, err
//		}
//		conn.sourceConn.Close() // nolint
//		return nil, err
//	}
//	t.push(conn)
//	go conn.proxyHandler(conn.targetConn, conn.sourceConn)
//	go conn.proxyHandler(conn.sourceConn, conn.targetConn)
//	go t.listenCloseConn(conn)
//	return conn, nil
//}
//
//func (t *WsProxy) push(conn *WsConn) {
//	t.mutex.Lock()
//	defer t.mutex.Unlock()
//	if conn.id == "" {
//		conn.id = gone.ID.SString()
//	}
//	t.conMap[conn.id] = conn
//}
//
//// listenCloseConn 监听连接直到代理连接关闭
//func (t *WsProxy) listenCloseConn(conn *WsConn) {
//	<-conn.doneCtx.Done()
//	// TODO 添加更多的后续操作
//	t.mutex.Lock()
//	defer t.mutex.Unlock()
//	defer conn.Close() // nolint
//	delete(t.conMap, conn.id)
//}
//
//// 数据代理
//func (t *WsConn) proxyHandler(src, dst net.Conn) {
//	var buffer = make([]byte, BYTES_SIZE)
//
//	defer t.cancelFunc()
//	for {
//		n1, err := src.Read(buffer)
//		if err != nil {
//			if needReadError(err) {
//				fmt.Println("读取源字节失败", err)
//			}
//			return
//		}
//		if n1 <= 0 {
//			continue
//		}
//		_, err = dst.Write(buffer[:n1])
//		if err != nil {
//			fmt.Println("写入目标字节失败")
//			if err.Error() != io.EOF.Error() {
//				if oe, ok := err.(*net.OpError); !ok || oe.Err != errCanceled { // nolint
//					fmt.Println("写入目标字节失败,目标ip:"+dst.RemoteAddr().String(), err)
//				}
//				return
//			}
//		}
//	}
//}
//func (t *WsConn) Close() error {
//	fmt.Println("targetAddr", t.targetAddr, "sourceAddr", t.sourceAddr, "断开连接")
//	err1 := t.targetConn.Close()
//	err2 := t.sourceConn.Close()
//	if err1 != nil {
//		return err1
//	}
//	return err2
//}
//
//func needReadError(err error) bool {
//	var oe = &net.OpError{}
//	if !errors.As(err, &oe) {
//		return true
//	}
//	if errors.Is(err, errCanceled) {
//		return false
//	}
//	if oe.Err.Error() == errWSAECONNRESET.Error() {
//		return true
//	}
//	if oe.Err.Error() == errNetClosing.Error() {
//		return false
//	}
//	return false
//}
//
//// fillPrefix 补全长度标记字符串，在前面加0
//func fillPrefix(value, l int) string {
//	str := strconv.Itoa(value)
//	strLen := len(str)
//	var buff strings.Builder
//	if l == strLen || l < strLen {
//		return str
//	}
//	count := l - strLen
//	for i := 0; i < count; i++ {
//		buff.WriteString("0")
//	}
//	buff.WriteString(str)
//	return buff.String()
//}
//
//func strToBytes(s string) []byte {
//	x := (*[2]uintptr)(unsafe.Pointer(&s)) // nolint
//	h := [3]uintptr{x[0], x[1], x[1]}
//	return *(*[]byte)(unsafe.Pointer(&h)) // nolint
//}
//func buildMsg(msg string) []byte {
//	buff := bytes.NewBuffer([]byte{0xff, 0x52})
//	msgLen := fillPrefix(len(msg), 4)
//	buff.Write(strToBytes(msgLen))
//	buff.Write(strToBytes(msg))
//	return buff.Bytes()
//}
